/*     */ package com.zimbra.cs.account.ldap;
/*     */ 
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.cs.account.EntrySearchFilter.AndOr;
/*     */ import com.zimbra.cs.account.EntrySearchFilter.Multi;
/*     */ import com.zimbra.cs.account.EntrySearchFilter.Operator;
/*     */ import com.zimbra.cs.account.EntrySearchFilter.Single;
/*     */ import com.zimbra.cs.account.EntrySearchFilter.Term;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class LdapFilterParser
/*     */ {
/*     */   private static enum FilterType
/*     */   {
/*  32 */     AND, 
/*  33 */     OR, 
/*  34 */     NOT;
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */     private FilterType() {}
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static EntrySearchFilter.Term parse(String filterStr)
/*     */     throws ServiceException
/*     */   {
/*  47 */     return parse(filterStr, 0, filterStr.length());
/*     */   }
/*     */   
/*     */   private static EntrySearchFilter.Term parse(String filterStr, int startPos, int endPos) throws ServiceException {
/*  51 */     String dbgInfo = "filter=" + filterStr + ", startPos=" + startPos + ", endPos=" + endPos;
/*     */     
/*     */ 
/*  54 */     if (endPos - startPos <= 0) {
/*  55 */       throw ServiceException.PARSE_ERROR(dbgInfo, null);
/*     */     }
/*     */     
/*  58 */     if (filterStr.charAt(startPos) == '(') {
/*  59 */       if (filterStr.charAt(endPos - 1) == ')') {
/*  60 */         startPos++;
/*  61 */         endPos--;
/*     */       } else {
/*  63 */         throw ServiceException.PARSE_ERROR("mising parentheses: " + dbgInfo, null);
/*     */       }
/*     */     }
/*     */     
/*  67 */     char c = filterStr.charAt(startPos);
/*  68 */     if (c == '&')
/*  69 */       return parseCompound(FilterType.AND, filterStr, startPos + 1, endPos);
/*  70 */     if (c == '|')
/*  71 */       return parseCompound(FilterType.OR, filterStr, startPos + 1, endPos);
/*  72 */     if (c == '!') {
/*  73 */       return parseCompound(FilterType.NOT, filterStr, startPos + 1, endPos);
/*     */     }
/*     */     
/*  76 */     return parseSimple(filterStr, startPos, endPos);
/*     */   }
/*     */   
/*     */   private static EntrySearchFilter.Multi parseCompound(FilterType filterType, String filterStr, int startPos, int endPos) throws ServiceException {
/*  80 */     String dbgInfo = "filter=" + filterStr + ", startPos=" + startPos + ", endPos=" + endPos;
/*     */     
/*  82 */     if (startPos == endPos) {
/*  83 */       throw ServiceException.PARSE_ERROR(dbgInfo, null);
/*     */     }
/*     */     
/*  86 */     if ((filterStr.charAt(startPos) != '(') || (filterStr.charAt(endPos - 1) != ')')) {
/*  87 */       throw ServiceException.PARSE_ERROR("mising parentheses: " + dbgInfo, null);
/*     */     }
/*     */     
/*  90 */     EntrySearchFilter.AndOr andOr = filterType == FilterType.OR ? EntrySearchFilter.AndOr.or : EntrySearchFilter.AndOr.and;
/*  91 */     boolean negation = filterType == FilterType.NOT;
/*  92 */     EntrySearchFilter.Multi multi = new EntrySearchFilter.Multi(negation, andOr);
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*  97 */     int pendingOpens = 0;
/*  98 */     int openPos = -1;
/*  99 */     for (int i = startPos; i < endPos; i++) {
/* 100 */       char c = filterStr.charAt(i);
/* 101 */       if (c == '(') {
/* 102 */         if (openPos < 0) {
/* 103 */           openPos = i;
/*     */         }
/*     */         
/* 106 */         pendingOpens++;
/* 107 */       } else if (c == ')') {
/* 108 */         pendingOpens--;
/* 109 */         if (pendingOpens == 0) {
/* 110 */           EntrySearchFilter.Term subTerm = parse(filterStr, openPos, i + 1);
/* 111 */           multi.add(subTerm);
/* 112 */           openPos = -1;
/* 113 */         } else if (pendingOpens < 0) {
/* 114 */           throw ServiceException.PARSE_ERROR("mising open parentheses: " + dbgInfo, null);
/*     */         }
/* 116 */       } else if (pendingOpens <= 0) {
/* 117 */         throw ServiceException.PARSE_ERROR("mising parentheses: " + dbgInfo, null);
/*     */       }
/*     */     }
/*     */     
/* 121 */     if (pendingOpens != 0) {
/* 122 */       throw ServiceException.PARSE_ERROR("mising parentheses: " + dbgInfo, null);
/*     */     }
/* 124 */     return multi;
/*     */   }
/*     */   
/*     */   private static EntrySearchFilter.Single parseSimple(String filterStr, int startPos, int endPos) throws ServiceException
/*     */   {
/* 129 */     String dbgInfo = "filter=" + filterStr + ", startPos=" + startPos + ", endPos=" + endPos;
/*     */     
/*     */ 
/* 132 */     int equalPos = -1;
/* 133 */     for (int i = startPos; i < endPos; i++) {
/* 134 */       if (filterStr.charAt(i) == '=') {
/* 135 */         equalPos = i;
/* 136 */         break;
/*     */       }
/*     */     }
/*     */     
/* 140 */     if ((equalPos == -1) || (equalPos == startPos)) {
/* 141 */       throw ServiceException.PARSE_ERROR(dbgInfo, null);
/*     */     }
/*     */     
/*     */     EntrySearchFilter.Operator op;
/*     */     int attrEndPos;
/* 146 */     switch (filterStr.charAt(equalPos - 1)) {
/*     */     case '>': 
/* 148 */       op = EntrySearchFilter.Operator.ge;
/* 149 */       attrEndPos = equalPos - 1;
/* 150 */       break;
/*     */     case '<': 
/* 152 */       op = EntrySearchFilter.Operator.le;
/* 153 */       attrEndPos = equalPos - 1;
/* 154 */       break;
/*     */     case '~': 
/* 156 */       throw ServiceException.PARSE_ERROR("approx match not supported " + dbgInfo, null);
/*     */     case ':': 
/* 158 */       throw ServiceException.PARSE_ERROR("extensible match not supported " + dbgInfo, null);
/*     */     default: 
/* 160 */       op = EntrySearchFilter.Operator.eq;
/* 161 */       attrEndPos = equalPos;
/*     */     }
/*     */     
/*     */     
/*     */ 
/* 166 */     String attrName = filterStr.substring(startPos, attrEndPos);
/* 167 */     if (attrName.length() == 0) {
/* 168 */       throw ServiceException.PARSE_ERROR("missing attr name" + dbgInfo, null);
/*     */     }
/*     */     
/* 171 */     String attrValue = filterStr.substring(equalPos + 1, endPos);
/* 172 */     if (attrValue.length() == 0) {
/* 173 */       throw ServiceException.PARSE_ERROR("missing attr value" + dbgInfo, null);
/*     */     }
/* 175 */     if ((op == EntrySearchFilter.Operator.eq) && 
/* 176 */       (!attrValue.equals("*")))
/*     */     {
/* 178 */       if ((attrValue.startsWith("*")) && (attrValue.endsWith("*"))) {
/* 179 */         if (attrValue.length() > 2) {
/* 180 */           op = EntrySearchFilter.Operator.has;
/* 181 */           attrValue = attrValue.substring(1, attrValue.length() - 1);
/*     */         }
/*     */       }
/* 184 */       else if (attrValue.startsWith("*")) {
/* 185 */         op = EntrySearchFilter.Operator.endswith;
/* 186 */         attrValue = attrValue.substring(1, attrValue.length());
/* 187 */       } else if (attrValue.endsWith("*")) {
/* 188 */         op = EntrySearchFilter.Operator.startswith;
/* 189 */         attrValue = attrValue.substring(0, attrValue.length() - 1);
/*     */       }
/*     */     }
/*     */     
/* 193 */     return new EntrySearchFilter.Single(false, attrName, op, attrValue);
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/account/ldap/LdapFilterParser.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */